using System;
using System.Collections.Generic;
using System.Threading;

using Jeffrey.XFramework.XCrawl;
using Jeffrey.XFramework.XNet;

namespace Jeffrey.XFramework
{
    public abstract class Fetcher : Processor
    {
        private static readonly Object s_SyncRoot = new Object();

        public Fetcher(String name, String description, String classname, String path)
            : this(name, description, classname, path, null) { }
        public Fetcher(String name, String description, String classname, String path, Filter filter)
            : base(name, description, classname, path, filter) { }

        protected abstract void Fetch(CrawlUri uri, ref XWebRequest xRquest);

        protected override sealed void innerProcess(CrawlUri uri)
        {
            try
            {
                XWebRequest request = m_Controller.m_RequestCollection[Thread.CurrentThread.ManagedThreadId];

                Fetch(uri, ref request);

                //to fetch the messages remained in the TCP/IP stack cause of the error...
                if (uri.m_Status != CrawlUri.StatusCode.S_Succeed)
                {
                    request.m_Response.GetContentString();
                    request.m_Response.Close();
                }

                //close the connection if necessary
                else if ( request.m_Response != null &&
                          (!request.m_Response.m_KeepAlive ||
                           !m_Controller.m_CrawlOrder.m_KeepAlive)
                        )
                    request.m_Response.Close();

                m_Controller.m_RequestCollection[Thread.CurrentThread.ManagedThreadId] = request;
            }
            catch (NullReferenceException)
            {
                uri.m_Status = CrawlUri.StatusCode.E_Fetch;
            }
            catch (StackOverflowException)
            {
                uri.m_Status = CrawlUri.StatusCode.E_Fetch;
            }
        }
        protected override void innerRejectProcess(CrawlUri curi)
        {
            /*
             * by default do nothing...
             */
        }
    }
}
